package com.example.javascaffold.utils;

import com.example.javascaffold.annotation.DtoCheck;
import com.example.javascaffold.exception.BaseException;
import com.example.javascaffold.exception.ParamException;
import com.example.javascaffold.model.dto.BaseDTO;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


/**
 * <p>
 *     <strong>DTO工具类</strong>
 * </p>
 * <li>
 * <p>
 *     <strong>示例1: 检验字段是否为空</strong> <br>
 *     需要传入的参数: DTO继承BaseDTO
 *     MyDTO dto = new MyDTO(); 继承自 BaseDTO
 *     DtoCheckUtils.check(dto)
 *     结果: 如果字段配置了 @DtoCheck 则会抛出异常
 * </p>
 * </li>
 * @author wzk
 *
 * @see
 * @since 15:39 2021/12/3
 **/
public class DtoCheckUtils {

    private DtoCheckUtils() {}
    
    /**
     * <p>
     *     <strong>示例1: 检验字段是否为空</strong> <br>
     *     需要传入的参数: DTO继承BaseDTO
     *     MyDTO dto = new MyDTO(); 继承自 BaseDTO
     *     DtoCheckUtils.check(dto)
     *     结果: 如果字段配置了 @DtoCheck 则会抛出异常
     * </p>
    **/
    public static void check(BaseDTO dto) throws BaseException {
        if (CheckParamUtils.isNullOrEmpty(dto)) {
            throw new ParamException("DTO为空");
        }
        // 获取对应对应的字段
        Field[] fields = dto.getClass().getDeclaredFields();
        for (Field field : fields) {
            DtoCheck dtoCheck = field.getAnnotation(DtoCheck.class);
            if (null == dtoCheck) {
                continue;
            }
            try {
                Method method = dto.getClass().getMethod("get" + toFirstUp(field.getName()));
                Object value = method.invoke(dto);
                if (CheckParamUtils.isNullOrEmpty(value)) {
                    throw new ParamException(dtoCheck.message());
                }
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 首字母大写
     * @author wzk
     * @date 13:44 2021/11/23
     **/
    private static String toFirstUp(String str) {
        char[] cs = str.toCharArray();
        cs[0] -= 32;
        return String.valueOf(cs);
    }

}
